package my.springboot.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import my.springboot.domain.primary.Withdrawal;
import my.springboot.exception.BaseException;
import my.springboot.po.bo.WithdrawalAdminBO;
import my.springboot.po.bo.WithdrawalListBO;
import my.springboot.po.enums.WithdrawalApplyEnum;
import my.springboot.po.enums.WithdrawalAuditEnum;
import my.springboot.po.vo.*;
import my.springboot.service.WithdrawalService;
import my.springboot.util.ReturnUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import static my.springboot.common.Constant.NORMAL_TIME_FORMAT;


/**
 * <p>
 * 提现历史 前端控制器
 * </p>
 *
 * @author fengbo
 * @since 2019-08-23
 */
@RestController
@RequestMapping("/withdrawal")
@Slf4j
public class WithdrawalController {

    @Autowired
    private WithdrawalService withdrawalService;

    @GetMapping("/page")
    public VoData<WithdrawalAdminVo> getWithdrawalList(WithdrawalAdminBO withdrawalForm) {
        return ReturnUtils.success(withdrawalService.getWithdrawalList(withdrawalForm));
    }

    @PostMapping("/{value}")
    public VoData addWithdrawal(@PathVariable String value, HttpServletRequest httpServletRequest) {
        int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
        BigDecimal money;
        try {
            money = new BigDecimal(value).stripTrailingZeros();
        } catch (Exception e) {
            log.error("提现金额不是数字 value=[{}]", value);
            throw new BaseException(ReturnCode.PARAM_ERROR);
        }
        if (money.scale() > 2) {
            log.error("提现金额精度错误 value=[{}]", value);
            throw new BaseException(ReturnCode.PARAM_ERROR);
        }
        if (day >= 21) {
            return ReturnUtils.fail(ReturnCode.WITHDRAWAL_TIME);
        }
        // 判断大于1元小于5000才可以体现
        if (money.compareTo(new BigDecimal(1)) < 0 || money.compareTo(new BigDecimal(5000)) > 0) {
            return ReturnUtils.fail(ReturnCode.WITHDRAWAL_LIMIT_OVER);
        }
        withdrawalService.saveWithdrawal(money, "127.0.0.1");
        return ReturnUtils.success();
    }

    @PostMapping("/audit")
    public VoData auditWithdrawal(@RequestBody WithdrawalVo withdrawalVo) {
        if (StringUtils.isEmpty(withdrawalVo.getValue())) {
            throw new BaseException(ReturnCode.PARAM_ERROR);
        }
        withdrawalService.updateWithdrawalById(withdrawalVo);
        return ReturnUtils.success();
    }

    @GetMapping("/list")
    public VoData<List<WithdrawalListVo>> getWithdrawalListByUserId(WithdrawalListBO withdrawalListForm) {
        int uid = 15;
        IPage<Withdrawal> page = new Page<>(1, 16);
        page = withdrawalService.page(page, statusConversion(withdrawalListForm.getStatus())
                .eq("user_id", uid)
                .eq(withdrawalListForm.getYear() != null, "DATE_FORMAT(create_time, '%Y')", withdrawalListForm.getYear())
                .eq(withdrawalListForm.getYear() != null && withdrawalListForm.getMonth() != null,
                        "DATE_FORMAT(create_time, '%m')", withdrawalListForm.getMonth())
                .orderByDesc("create_time")
        );
        List<WithdrawalListVo> result = new ArrayList<>(page.getRecords().size());
        page.getRecords().forEach(withdrawal -> {
            WithdrawalListVo withdrawalVo = new WithdrawalListVo();
            withdrawalVo.setId(withdrawal.getId());
            withdrawalVo.setRealAmount(withdrawal.getRealAmount());
            if (withdrawal.getCreateTime() != null) {
                withdrawalVo.setCreateTime(DateFormatUtils.format(withdrawal.getCreateTime(), NORMAL_TIME_FORMAT));
            }
            withdrawalVo.setStatus(withdrawal.getAuditStatus(), withdrawal.getApplyStatus());
            result.add(withdrawalVo);
        });
        return ReturnUtils.success(result);
    }

    /**
     * 前后台状态对应表
     * 前台状态    审核状态    划款状态
     * 已到账      已审核      已划款
     * 审核中      待审核      未划款
     * 打款失败    已审核     划款失败
     * 打款失败    已拒绝      未划款
     * @param status 前台状态
     * @return 查询参数
     */
    private QueryWrapper<Withdrawal> statusConversion(Integer status) {
        QueryWrapper<Withdrawal> queryWrapper = new QueryWrapper<>();
        if (Integer.valueOf(0).equals(status)) {
            queryWrapper.eq("audit_status", WithdrawalAuditEnum.UN_REVIEWED.getCode())
                    .eq("apply_status", WithdrawalApplyEnum.UN_REVIEWED.getCode());
        } else if (Integer.valueOf(1).equals(status)) {
            queryWrapper.eq("audit_status", WithdrawalAuditEnum.APPROVED.getCode())
                    .eq("apply_status", WithdrawalApplyEnum.APPROVED.getCode());
        } else if (Integer.valueOf(2).equals(status)) {
            queryWrapper.and(i -> i.eq("audit_status", WithdrawalAuditEnum.REJECTED.getCode())
                    .eq("apply_status", WithdrawalApplyEnum.UN_REVIEWED.getCode()))
                    .or(i -> i.eq("audit_status", WithdrawalAuditEnum.APPROVED.getCode())
                            .eq("apply_status", WithdrawalApplyEnum.FAILED.getCode()));
        }
        return queryWrapper;
    }
}

